﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Android_Helper.android
{
    public class SwaggerUtils
    {
        public static string getDefaultProcess(string SwaggerText)
        {
            string ret = string.Empty;
            Regex regex = new Regex("/api/v2(.*)");
            Match match = regex.Match(SwaggerText);
            string apiValue = string.Empty;
            if (match.Success)
            {
                apiValue = match.Groups[1].ToString();
            }

            string apiKey = apiValue.Replace("/", "_").Replace("-", "_").ToUpper();
            string url = "\n\nServerURL:\n";
            url += "public static final String " + apiKey + " = API_URL_ROOT + \"" + apiValue + "\";";
            ret = url;

            String func = apiKey.ToLower();
            String finalfunc = "";
            int idx = -1;
            char[] chars = func.ToCharArray();
            for (int i = 0; i < chars.Count(); i++)
            {
                if (chars[i] == '_')
                {
                    idx = i;
                    continue;
                }
                if ((i > 1) && (i == idx + 1))
                {
                    finalfunc += chars[i].ToString().ToUpper();
                    continue;
                }
                finalfunc += chars[i].ToString();
            }
            String funcparams = "";
            List<String> ls = new List<string>();

            regex = new Regex("^Parameters(.*)Response\\sMessages", RegexOptions.Singleline | RegexOptions.Multiline);
            match = regex.Match(SwaggerText);
            if (match.Success)
            {
                funcparams = match.Groups[1].ToString();
            }
            if (!string.IsNullOrEmpty(funcparams))
            {
                funcparams = funcparams.Substring(funcparams.IndexOf("Data Type") + 9);
                funcparams = funcparams.Replace("query", "");
                funcparams = funcparams.Replace("string", "");
                funcparams = funcparams.Replace("long", "");
                funcparams = funcparams.Replace("integer", "");
                funcparams = funcparams.Replace("boolean", "");
                funcparams = funcparams.Replace("double", "");
                foreach (string s in funcparams.Split('\n'))
                {
                    String s1 = s.Trim();
                    if (ls.IndexOf(s1) == -1)
                    {
                        ls.Add(s1);
                    }
                }
                ls.Remove("");
                funcparams = "";
                foreach (string s in ls)
                {
                    funcparams += "String " + s + ", ";
                }
            }
            String parambody = "";
            parambody = "Map<String, String> params=new ArrayMap<>();\n";
            foreach (string s in ls)
            {
                parambody += "params.put(\"" + s + "\", " + s + ");\n";
            }
            parambody += "params.put(\"token\", SecurityUtils.getToken());\n";
            string funcbody = "return ServerAPIUtils.post(context, ServerUrl." + apiKey + ", params, stringCallback);";
            string funcdeclare = "public static Observable<String> " + finalfunc + "(Context context, " + funcparams + "StringCallback stringCallback){\n" +
                parambody +
                funcbody +
                "\n}";
            ret += "\n\n" + funcdeclare;
            return ret;
        }

        public static string GetSwaggerUrls(MatchCollection urlmatches)
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (Match match in urlmatches)
            {
                if (match.Success)
                {
                    string apiValue = match.Groups[1].ToString();
                    string apiKey = apiValue.Replace("/", "_").Replace("-", "_").ToUpper();
                    string url = "public static final String " + apiKey + " = API_URL_ROOT + \"" + apiValue + "\";";
                    stringBuilder.AppendLine();
                    stringBuilder.AppendLine(url);
                }
            }
            
            return stringBuilder.ToString();
        }

        public static string GetSwaggerFunctions(MatchCollection urlmatches, MatchCollection funcmatches)
        {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i=0; i<funcmatches.Count; i++)
            {
                string ret = string.Empty;
                Match urlmatch = urlmatches[i];
                string apiValue = urlmatch.Groups[1].ToString();
                string apiKey = apiValue.Replace("/", "_").Replace("-", "_").ToUpper();

                String func = apiKey.ToLower();
                String finalfunc = "";
                int idx = -1;
                char[] chars = func.ToCharArray();
                for (int charpos = 0; charpos < chars.Count(); charpos++)
                {
                    if (chars[charpos] == '_')
                    {
                        idx = charpos;
                        continue;
                    }
                    if ((charpos > 1) && (charpos == idx + 1))
                    {
                        finalfunc += chars[charpos].ToString().ToUpper();
                        continue;
                    }
                    finalfunc += chars[charpos].ToString();
                }
                String funcparams = "";
                List<String> ls = new List<string>();

                Match funcmatch = funcmatches[i];
                if (funcmatch.Success)
                {
                    funcparams = funcmatch.Groups[1].ToString();
                }
                if (!string.IsNullOrEmpty(funcparams))
                {
                    funcparams = funcparams.Substring(funcparams.IndexOf("Data Type") + 9);
                    funcparams = funcparams.Replace("query", "");
                    funcparams = funcparams.Replace("string", "");
                    funcparams = funcparams.Replace("long", "");
                    funcparams = funcparams.Replace("integer", "");
                    funcparams = funcparams.Replace("boolean", "");
                    funcparams = funcparams.Replace("double", "");
                    foreach (string s in funcparams.Split('\n'))
                    {
                        String s1 = s.Trim();
                        if (ls.IndexOf(s1) == -1)
                        {
                            ls.Add(s1);
                        }
                    }
                    ls.Remove("");
                    funcparams = "";
                    foreach (string s in ls)
                    {
                        funcparams += "String " + s + ", ";
                    }
                }
                String parambody = "";
                parambody = "Map<String, String> params=new ArrayMap<>();\n";
                foreach (string s in ls)
                {
                    parambody += "params.put(\"" + s + "\", " + s + ");\n";
                }
                parambody += "params.put(\"token\", SecurityUtils.getToken());\n";
                string funcbody = "return ServerAPIUtils.post(context, ServerUrl." + apiKey + ", params, stringCallback);";
                string funcdeclare = "public static Observable<String> " + finalfunc + "(Context context, " + funcparams + "StringCallback stringCallback){\n" +
                    parambody +
                    funcbody +
                    "\n}";
                ret += "\n\n" + funcdeclare;

                stringBuilder.AppendLine(ret);
            }
            
            return stringBuilder.ToString();
        }

        public static string GetSwaggerDao(string SwaggerText)
        {
            StringBuilder stringBuilder = new StringBuilder();
            Regex regex = new Regex("/api/v2(.*)");
            MatchCollection urlmatches = regex.Matches(SwaggerText);
            
            
            regex = new Regex("^Parameters(.*?)Response\\sMessages", RegexOptions.Singleline | RegexOptions.Multiline);
            MatchCollection funcmatches = regex.Matches(SwaggerText);

            if (urlmatches.Count != funcmatches.Count)
            {
                stringBuilder.AppendLine("URL和FUNCTION数量不匹配，请手动。");
                return stringBuilder.ToString();
            }
            stringBuilder.AppendLine(GetSwaggerUrls(urlmatches));

            stringBuilder.AppendLine(GetSwaggerFunctions(urlmatches, funcmatches));

            return stringBuilder.ToString();
        }
    }
}
